/* eslint-disable vue/no-setup-props-destructure */
import type { mapViewPropsType, mapViewStateType } from './typings'
import { defineComponent, onMounted, reactive, watch, shallowRef } from 'vue'
import { useStore } from 'vuex'
import { ElLoading } from 'element-plus'
import { isPlainObject, cloneDeep } from 'lodash'
import useAMap from '~/hooks/useAMap'
import useVuexGetters from '~/hooks/useVuexGetters'

export default defineComponent({
  name: 'MapView',
  props: ['id', 'clickon', 'marker'],
  emits: ['changeAddress', 'clickMarker'],
  setup(props: mapViewPropsType, { emit, expose }) {
    const store = useStore()
    const { id = 'container' } = props
    const state = reactive<mapViewStateType>({
      currentMarker: undefined,
      currentMarkerShadow: undefined // 阴影
    })
    // 获取租户设置的坐标
    const getCurrentTenant = useVuexGetters('user', ['userAddressInfo'])

    const [mapRef, aMapRef, amapIconRef] = useAMap(
      id,
      {
        center: [
          getCurrentTenant.userAddressInfo.value.lon,
          getCurrentTenant.userAddressInfo.value.lat
        ],
        zoom: 11
      },
      initAMap
    )

    watch(
      () => props.marker,
      () => {
        if (state.currentMarker && props.marker) {
          const element = cloneDeep(props.marker)
          mapRef.value.setCenter([props.marker!.lng, props.marker!.lat])
          state.currentMarker.setPosition([element.lng, element.lat])
          state.currentMarkerShadow!.setCenter([element.lng, element.lat])
          handleCurrentMarkerAddressList(element.lng, element.lat)
        } else if (!state.currentMarker && props.marker && mapRef.value) {
          handleAddAMapMarker(props.marker!.lng, props.marker!.lat, props.marker)
        }
      },
      { deep: true }
    )

    onMounted(() => {
      store.dispatch('user/GetCurrentTenant') // 获取租户设置的坐标
    })

    const loading = ElLoading.service({
      target: `#${id}`,
      lock: true,
      text: '加载中'
    })

    // 添加marker点击事件 将储存的值发送给父元素
    const handleClickMarkerCallback = (e: { target: mapViewStateType['currentMarker'] }) => {
      emit('clickMarker', e?.target!?.getExtData?.())
    }

    // 拖拽 移动标记点时 更新标记点的阴影位置
    const handleDraggingMarkerCallback = () => {
      const markerPosition = state.currentMarker!.getPosition()
      state.currentMarkerShadow!.setCenter([markerPosition?.lng, markerPosition?.lat])
    }

    // 拖拽 移动结束后 标记点并查询地址
    const handleDragMarkerCallback = () => {
      const markerPosition = state.currentMarker!.getPosition()
      mapRef.value.setCenter([markerPosition.lng, markerPosition.lat], true)
      state.currentMarkerShadow!.setCenter([markerPosition.lng, markerPosition.lat])
      handleCurrentMarkerAddressList(markerPosition.lng, markerPosition.lat)
    }

    // 清除标记点
    const handleClearAMapMarker = () => {
      mapRef.value.clearMap()
      state.currentMarker = undefined
      state.currentMarkerShadow = undefined
    }

    // 添加标点
    const handleAddAMapMarker = (
      lng: number,
      lat: number,
      item?: mapViewStateType['currentMarker']
    ) => {
      if (state.currentMarker || state.currentMarkerShadow) {
        handleClearAMapMarker()
      }
      const marker = new aMapRef.value.Marker({
        icon: amapIconRef.value,
        position: [lng, lat],
        offset: [-12, -22],
        // zooms: [2, 18],
        extData: item || {},
        draggable: true // 可拖拽
      })
      // .setExtDate(item || {})
      // 阴影
      const markerShadow = new aMapRef.value.CircleMarker({
        center: [lng, lat],
        radius: 50,
        // zooms: [2, 18],
        fillColor: '#FFBBBB',
        fillOpacity: 0.3,
        strokeOpacity: 0
      })
      state.currentMarker = marker
      state.currentMarkerShadow = markerShadow // 阴影
      mapRef.value.add(marker)
      mapRef.value.add(markerShadow) // 阴影
      mapRef.value.setFitView()
      marker.on('click', handleClickMarkerCallback)
      marker.on('dragging', handleDraggingMarkerCallback) // 拖拽过程中
      marker.on('dragend', handleDragMarkerCallback) // 拖拽结束
      handleCurrentMarkerAddressList(lng, lat)
    }

    // 单击地图事件回调
    const handleClickAMapCallback = (mapsEvent: { lnglat: { lng: number; lat: number } }) => {
      const {
        lnglat: { lng, lat }
      } = mapsEvent
      if (state.currentMarker) return // 只有新增的可打点一次, 此外均不可打点, 所以这句暂加上
      handleAddAMapMarker(lng, lat)
    }

    const handleCurrentMarkerAddressList = (lng: number, lat: number) => {
      aMapRef.value.plugin(['AMap.Geocoder'], () => {
        const geocoder = new aMapRef.value.Geocoder({
          radius: 1000, // 以已知坐标为中心点，radius为半径，返回范围内兴趣点和道路信息
          extensions: 'all' // 返回地址描述以及附近兴趣点和道路信息，默认“base”
        })
        geocoder.getAddress(
          new aMapRef.value.LngLat(lng, lat),
          (
            status: string,
            result: { info: string; regeocode: { formattedAddress: string; addressComponent: any } }
          ) => {
            if (status === 'complete' && result.info === 'OK') {
              const defectAddress = result.regeocode.formattedAddress
              const addressComponent = result.regeocode.addressComponent
              const params = {
                latitude: lat,
                longitude: lng,
                defectAddress,
                region: `${addressComponent.province}-${addressComponent.city}-${addressComponent.district}`
              }
              emit('changeAddress', params)
            } else {
              emit('changeAddress', [])
            }
          }
        )
      })
    }

    // 根据props.markers来设置坐标点回调
    const handleSetMarkerByPropsMarkers = () => {
      if (props.marker && aMapRef.value) {
        const timer = setTimeout(() => {
          if (isPlainObject(props.marker)) {
            const item = props.marker
            if (item?.lng) {
              handleAddAMapMarker(
                (item as Record<string, any>)?.lng,
                (item as Record<string, any>)?.lat,
                item as any
              )
            }
          }
          clearTimeout(timer)
        }, 0)
      }
    }

    //  卫星地图展示切换
    const satellite = shallowRef()
    const satelliteChangingOver = (value: boolean) => {
      if (!value) {
        mapRef.value.removeLayer(satellite.value)
      } else {
        mapRef.value.addLayer(satellite.value)
      }
    }

    // 初始化map事件
    function initAMap() {
      // 放大缩小的加减按钮
      const toolBar = new aMapRef.value.ToolBar({
        position: {
          top: '20px',
          right: '20px'
        }
      })
      mapRef.value.addControl(toolBar) // 放大缩小的加减按钮
      loading.close()
      const { clickon = false } = props
      if (clickon) mapRef.value.on('click', handleClickAMapCallback)
      if (props.marker && aMapRef.value) handleSetMarkerByPropsMarkers()

      satellite.value = new aMapRef.value.TileLayer.Satellite()
      // mapRef.value.addLayer(satellite.value)
    }

    expose({
      mapRef,
      aMapRef,
      clearCurrentMarker: handleClearAMapMarker,
      setMarkersByPropsMarkers: handleSetMarkerByPropsMarkers,
      // handleClickAMapCallback // 只有新增的可打点一次, 此外均不可打点, 所以这段暂注释掉
      satelliteChangingOver
    })
    return () => <section id={id}></section>
  }
})
